package simpleExample;

import gridworld.Environment;

import jade.core.Agent;
import jade.core.behaviours.Behaviour;

import java.awt.Point;

import java.util.HashSet;


public class MixedBehaviour extends Behaviour {
    //the current position of the agent
    private Point currentPosition;
    
    //the destination of the agent in active working
    private Point destination;
    
    String agentName;
    
    //the location of all known bombs
    HashSet<Point> bombs;
    
    HashSet<Point> traps;
    
    private boolean morePositions;
    
    private byte state;
    
    private boolean toEast;
    
    public MixedBehaviour(Agent agent) {
        super(agent);
        agentName = agent.getLocalName();
        bombs = new HashSet<Point>();
        traps = new HashSet<Point>();
        //set destination to the furthermost NE point
        destination = new Point(0, 0);
        currentPosition = Environment.getPosition(agentName);
        morePositions = true;
        toEast = true;
    }

    public void action() {
        //add all bombs and traps
        traps.addAll(Environment.senseTraps(agentName));
        bombs.addAll(Environment.senseBombs(agentName));
        switch(state) {
        case SimpleAgent.NO_KNOWLEDGE: {
            //if there is no knowledge about bombs
            if(bombs.isEmpty()) {
                //search the environment  
                searchEnvironment();  
            } else {
                //get a bomb to pick up
                state = SimpleAgent.KNOW_BOMB_LOCATION;
                destination = bombs.iterator().next();
                //set last explored position
            }
        }break;
        case SimpleAgent.KNOW_BOMB_LOCATION: {
          currentPosition = Environment.getPosition(agentName);                                       
          if(destination.equals(currentPosition)) {
              //we can pick up the bomb
              Environment.takeBomb(agentName);
              bombs.remove(destination);
              state = SimpleAgent.HAS_BOMB;
              //locate the nearest trap for dropping the bomb
              destination = SimpleAgent.getNearestTarget(currentPosition, 
                                                         traps);
          } else {
              //continue moving to destination
              moveToDestination();
          }
        }break;
        case SimpleAgent.HAS_BOMB: {
            //there is a trap location available
            if(destination != null) {
                currentPosition = Environment.getPosition(agentName);
                //agent is in the same location as a trap
                if(destination.equals(currentPosition)) {
                    //drop the bomb and see if you know another bomb location
                    Environment.dropBomb(agentName);
                    state = SimpleAgent.NO_KNOWLEDGE;
                    //return to last explored position to resume exploration
                } else {
                    //continue moving towards the trap
                    moveToDestination();
                }
            } else {
                //continue moving in the environment
                searchEnvironment();
                destination = SimpleAgent.getNearestTarget(currentPosition, 
                                                           traps);
            }
        }break;
        }
    }

    public boolean done() {
        return ((SimpleAgent)myAgent).getPositionsToVisit() == 0;
    }
    
    private void searchEnvironment() {
        currentPosition = Environment.getPosition(agentName);
        ((SimpleAgent)myAgent).moveAgent(null);
    }
    
    private void moveToDestination() {
        currentPosition = Environment.getPosition(agentName);
        ((SimpleAgent)myAgent).moveAgent(destination);
    }
    
}
